home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / e-n / golded / data / tools / source / ed.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-16  |  11.9 KB  |  490 lines

  1. /* -----------------------------------------------------------------------------
  2.  
  3.   ED 2.4 - GoldED quick starter, ©1995 Dietmar Eilert.
  4.  
  5.   This is C source code of ED to give you an idea of how to address GoldED
  6.   from other applications. Feel free to change this code. Dice:
  7.  
  8.   dcc ed.c sprintf.a -// -proto -mRR -mi -pr -2.0 -o ram:ED
  9.  
  10.   ------------------------------------------------------------------------------
  11. */
  12.  
  13. /// "includes"
  14.  
  15. #include <amiga20/exec/exec.h>
  16. #include <string.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <stdlib.h>
  20. #include <stdarg.h>
  21. #include <amiga20/intuition/intuition.h>
  22. #include <amiga20/dos/dos.h>
  23. #include <amiga20/dos/dosextens.h>
  24. #include <amiga20/dos/rdargs.h>
  25. #include <amiga20/dos/dostags.h>
  26. #include <amiga20/workbench/startup.h>
  27. #include <amiga20/workbench/workbench.h>
  28. #include <amiga20/rexx/errors.h>
  29. #include <amiga20/rexx/rxslib.h>
  30.  
  31. #include <amiga20/clib/alib_protos.h>
  32. #include <amiga20/clib/dos_protos.h>
  33. #include <amiga20/clib/exec_protos.h>
  34. #include <amiga20/clib/icon_protos.h>
  35. #include <amiga20/clib/intuition_protos.h>
  36. #include <amiga20/clib/utility_protos.h>
  37. #include <amiga20/clib/rexxsyslib_protos.h>
  38. #include <amiga20/clib/wb_protos.h>
  39.  
  40. #define PRAGMAS
  41.  
  42. #ifdef PRAGMAS
  43.  
  44. #include "Pragmas/exec.h"
  45. #include "Pragmas/disk.h"
  46. #include "Pragmas/diskfont.h"
  47. #include "Pragmas/dynamic.h"
  48. #include "Pragmas/gadtools.h"
  49. #include "Pragmas/keymap.h"
  50. #include "Pragmas/graphics.h"
  51. #include "Pragmas/icon.h"
  52. #include "Pragmas/input.h"
  53. #include "Pragmas/intuition.h"
  54. #include "Pragmas/layers.h"
  55. #include "Pragmas/locale.h"
  56. #include "Pragmas/misc.h"
  57. #include "Pragmas/timer.h"
  58. #include "Pragmas/wb.h"
  59. #include "Pragmas/xpkmaster.h"
  60. #include "Pragmas/amigaguide.h"
  61. #include "Pragmas/reqtools.h"
  62.  
  63. #endif
  64.  
  65. #define Prototype        extern
  66. #define MAX_LEN          120
  67. #define ARGBUFFER_SIZE   10500
  68. #define ARGBUFFER_LIMIT  10000
  69.  
  70. ///
  71. /// "prototypes"
  72.  
  73. Prototype void   main(ULONG, UBYTE **);
  74. Prototype int    wbmain(struct WBStartup *);
  75. Prototype void   Action(UBYTE *, UBYTE *, UBYTE *, BOOL, BOOL, ULONG *, UBYTE *, BOOL);
  76. Prototype UBYTE  *StartGED(UBYTE *, UBYTE *, UBYTE *, BOOL, BOOL);
  77. Prototype ULONG *SendRexxCommand(UBYTE *, UBYTE *, struct MsgPort *);
  78. Prototype UBYTE  *LookForGED(UBYTE *);
  79. Prototype UBYTE  *myprintf(UBYTE *, UBYTE*, ...);
  80. Prototype UBYTE  *xsprintf(UBYTE *, APTR);
  81. Prototype BOOL   FindAssign(UBYTE *);
  82.  
  83. extern struct Library *IconBase;
  84. extern struct Library *DOSBase;
  85. extern struct Library *SysBase;
  86. extern struct Library *IntuitionBase;
  87.  
  88. ///
  89. /// "entry points"
  90.  
  91. /* --------------------------------------- main --------------------------------
  92.  
  93.  CLI entry point. Parse command line - create a string <argBuffer> containing
  94.  provided  file  names  (file names are made absolute). This string has to be
  95.  FreeVec()'ed later on. Additionally, command line options are checked.
  96.  
  97. */
  98.  
  99. void
  100. main(argc, argv)
  101.  
  102. ULONG argc;
  103. UBYTE *argv[];
  104. {
  105.     UBYTE *argBuffer;
  106.  
  107.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  108.  
  109.         struct RDArgs *rdArgs;
  110.  
  111.         ULONG args[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  112.  
  113.         BOOL fast = FALSE;
  114.  
  115.         if (rdArgs = ReadArgs("C=CONFIG/K,S=SCREEN/K,Y=STICKY/S,F=FILE/M,HIDE/S,-STICKY/S,L=LINE/N,A=AREXX/K,FAST/S", args, NULL)) {
  116.  
  117.             if (args[8])                             // FAST/S
  118.                 fast = TRUE;
  119.  
  120.             if (args[3]) {
  121.  
  122.                 UBYTE **nextFile, path[MAX_LEN + 1];
  123.                 BPTR    lock;
  124.  
  125.                 for (nextFile = (UBYTE **)args[3]; *nextFile; ++nextFile) {
  126.  
  127.                     strcpy(path, *nextFile);
  128.  
  129.                     if (lock = Lock(path, ACCESS_READ)) {
  130.  
  131.                         NameFromLock(lock, path, MAX_LEN);
  132.                         UnLock(lock);
  133.                     }
  134.                     else if (strchr(path, ':') == NULL) {
  135.  
  136.                         GetCurrentDirName(path, MAX_LEN);
  137.  
  138.                         AddPart(path, *nextFile, MAX_LEN);
  139.                     }
  140.  
  141.                     strcat(argBuffer, xsprintf("\42%s\42", path));
  142.  
  143.                     // files are specified: disable AutoDesktop feature of GoldED
  144.  
  145.                     fast = TRUE;
  146.  
  147.                     if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  148.                         break;
  149.                 }
  150.             }
  151.  
  152.             Action(argBuffer, (UBYTE *)args[0], (UBYTE *)args[1], (BOOL)args[2] || (BOOL)args[5], (BOOL)args[4] || (BOOL)args[5], (ULONG *)args[6], (UBYTE *)args[7], fast);
  153.  
  154.             FreeArgs(rdArgs);
  155.         }
  156.         else
  157.             exit(20);
  158.     }
  159.     exit(0);
  160. }
  161.  
  162. /* ------------------------------------ wbmain ---------------------------------
  163.  
  164.  Workbench entry point. Read tooltypes of ED icon to decide wether user prefers
  165.  a special configuration/public screen.
  166.  
  167. */
  168.  
  169. int
  170. wbmain(struct WBStartup *wbs)
  171. {
  172.     UBYTE *argBuffer;
  173.  
  174.     if (argBuffer = AllocVec(ARGBUFFER_SIZE, MEMF_PUBLIC | MEMF_CLEAR)) {
  175.  
  176.         struct DiskObject *diskObject;
  177.         UBYTE             *config, *screen, *arexx, progName[MAX_LEN + 1];
  178.         BOOL               hide, fast;
  179.  
  180.         screen = NULL;
  181.         config = NULL;
  182.         arexx  = NULL;
  183.  
  184.         hide = FALSE;
  185.         fast = FALSE;
  186.  
  187.         NameFromLock(GetProgramDir(), progName, MAX_LEN);
  188.  
  189.         AddPart(progName, wbs->sm_ArgList[0].wa_Name, MAX_LEN);
  190.  
  191.         if (diskObject = GetDiskObject(progName)) {
  192.  
  193.             config = FindToolType(diskObject->do_ToolTypes, "CONFIG");
  194.             screen = FindToolType(diskObject->do_ToolTypes, "SCREEN");
  195.             arexx  = FindToolType(diskObject->do_ToolTypes, "AREXX" );
  196.  
  197.             if (FindToolType(diskObject->do_ToolTypes, "HIDE"))
  198.                 hide = TRUE;
  199.  
  200.             if (FindToolType(diskObject->do_ToolTypes, "FAST"))
  201.                 fast = TRUE;
  202.         }
  203.  
  204.         if (--wbs->sm_NumArgs) {
  205.  
  206.             UBYTE file[MAX_LEN + 1];
  207.  
  208.             struct WBArg *wbArg = wbs->sm_ArgList;
  209.  
  210.             while ((wbs->sm_NumArgs)--) {
  211.  
  212.                 ++wbArg;
  213.  
  214.                 NameFromLock( wbArg->wa_Lock, file, MAX_LEN);
  215.                 AddPart(file, wbArg->wa_Name, MAX_LEN);
  216.  
  217.                 strcat(argBuffer, xsprintf("\42%s\42", file));
  218.  
  219.                 // files are specified: disable AutoDesktop feature of GoldED
  220.  
  221.                 fast = TRUE;
  222.  
  223.                 if (strlen(argBuffer) > ARGBUFFER_LIMIT)
  224.                     break;
  225.             }
  226.         }
  227.  
  228.         Action(argBuffer, config, screen, FALSE, hide, NULL, arexx, fast);
  229.  
  230.         if (diskObject)
  231.             FreeDiskObject(diskObject);
  232.     }
  233.  
  234.     exit(0);
  235. }
  236.  
  237. ///
  238. /// "main routine"
  239.  
  240. /* ------------------------------------ Action ---------------------------------
  241.  
  242.  Run GoldED if no running instance of GED is found (note:  running  GED  will
  243.  open  a  first  window,  i.e. no need to open a further one unless files are
  244.  specified). Send LOCK message to running GoldED. Wait  for  positive  reply,
  245.  pass  our  list of <files> to that editor, unlock editor (use delayed unlock
  246.  if <sticky> is specified).
  247.  
  248. */
  249.  
  250. void
  251. Action(files, config, screen, sticky, hide, line, arexx, fast)
  252.  
  253. UBYTE *files, *config, *screen, *arexx;
  254. ULONG *line;
  255. BOOL   sticky, hide, fast;
  256. {
  257.     static UBYTE version[] = "$VER: ED 2.4 (" __COMMODORE_DATE__ ")";
  258.  
  259.     BOOL   useResident;
  260.     ULONG *result;
  261.     UBYTE *host;
  262.  
  263.     useResident = ((host = LookForGED(arexx)) != NULL);
  264.  
  265.     if (useResident == FALSE)
  266.         host = StartGED(config, screen, arexx, hide, fast);
  267.  
  268.     // any further action required (besides running GoldED) ?
  269.  
  270.     if (host && (*files || (useResident && (hide == FALSE)))) {
  271.  
  272.         struct MsgPort *replyPort;
  273.  
  274.         if (replyPort = CreateMsgPort()) {
  275.  
  276.             if (result = SendRexxCommand(host, "LOCK CURRENT", replyPort)) {
  277.  
  278.                 if (*result == RC_OK) {
  279.  
  280.                     if (config && useResident)
  281.                         SendRexxCommand(host, xsprintf("PREFS LOAD SMART CONFIG=\42%s\42 ", config), replyPort);
  282.  
  283.                     if (*files)
  284.                         strins(files, "OPEN SMART QUIET ");
  285.                     else
  286.                         strcpy(files, "MORE SMART");
  287.  
  288.                     SendRexxCommand(host, files, replyPort);
  289.  
  290.                     if (line)
  291.                         SendRexxCommand(host, xsprintf("GOTO LINE=%ld UNFOLD=TRUE", (APTR)*line), replyPort);
  292.  
  293.                     SendRexxCommand(host, sticky ? "UNLOCK STICKY" : "UNLOCK", replyPort);
  294.                 }
  295.             }
  296.  
  297.             DeleteMsgPort(replyPort);
  298.         }
  299.     }
  300.  
  301.     FreeVec(files);
  302. }
  303.  
  304. ///
  305. /// "misc"
  306.  
  307. /* -------------------------------- FindAssign ---------------------------------
  308.  
  309.  Check whether assign exists without annoying 'insert drive' requester
  310.  
  311. */
  312.  
  313. BOOL
  314. FindAssign(assign)
  315.  
  316. UBYTE *assign;
  317. {
  318.     BOOL success = (FindDosEntry(LockDosList(LDF_ASSIGNS | LDF_READ), assign, LDF_ASSIGNS) != NULL);
  319.  
  320.     UnLockDosList(LDF_ASSIGNS | LDF_READ);
  321.  
  322.     return(success);
  323. }
  324.  
  325.  
  326. /* ----------------------------------- LookForGED ----------------------------
  327.  
  328.  Look for running GoldED task (check <host> and GOLDED.1 to GOLDED.9)
  329.  
  330. */
  331.  
  332. UBYTE *
  333. LookForGED(host)
  334.  
  335. UBYTE *host;
  336. {
  337.     if (host && FindPort(host))
  338.  
  339.         return(host);
  340.  
  341.     else {
  342.  
  343.         static UBYTE name[] = "GOLDED.1";
  344.  
  345.         while (name[7] <= '9') {
  346.  
  347.             if (FindPort(name))
  348.                 return(name);
  349.             else
  350.                 ++name[7];
  351.         } 
  352.  
  353.         return(NULL);
  354.     }
  355. }
  356.  
  357. /* ------------------------------------- StartGED -----------------------------
  358.  
  359.  Launch a new GoldED task. Look for "GOLDED:" assign. Add assign if  none  is
  360.  found (defaultPath[] is set by the installer script). Return pointer to host
  361.  name (or NULL). Screen/config keywords are considered.
  362.  
  363. */
  364.  
  365. UBYTE *
  366. StartGED(config, screen, arexx, hide, fast)
  367.  
  368. UBYTE *config, *screen, *arexx;
  369. BOOL   hide, fast;
  370. {
  371.     static UBYTE host[255], defaultPath[255] = "$GOLDED";
  372.  
  373.     UBYTE command[MAX_LEN + 1];
  374.  
  375.     if (FindAssign("GOLDED") == FALSE)
  376.         AssignLock("GOLDED", Lock(defaultPath, ACCESS_READ));
  377.  
  378.     if (arexx)
  379.         strcpy(host, arexx);
  380.     else
  381.         strcpy(host, "GOLDED.1");
  382.  
  383.     strcpy(command, xsprintf("GOLDED:GOLDED AREXX=%s", host));
  384.  
  385.     if (hide)
  386.         strcat(command, " HIDE");
  387.  
  388.     if (fast)
  389.         strcat(command, " FAST");
  390.  
  391.     if (config)
  392.         strcat(command, xsprintf(" CONFIG=\42%s\42", config));
  393.  
  394.     if (screen)
  395.         strcat(command, xsprintf(" SCREEN=%s", screen));
  396.  
  397.     if (SystemTags(command, SYS_Asynch, TRUE, SYS_Input, NULL, SYS_Output, NULL, NP_StackSize, 8192, TAG_DONE) == 0) {
  398.  
  399.         UWORD try;
  400.  
  401.         for (try = 50; try; try--, Delay(10))
  402.             if (FindPort(host))
  403.                 return(host);
  404.     }
  405.  
  406.     return(NULL);
  407. }
  408.  
  409. /* --------------------------------- xsprintf ----------------------------------
  410.  
  411.  sprintf frontend (returns pointer to static buffer)
  412.  
  413. */
  414.  
  415. UBYTE *
  416. xsprintf(template, data)
  417.  
  418. UBYTE *template;
  419. APTR  data;
  420. {
  421.     static UBYTE buffer[MAX_LEN + 1];
  422.  
  423.     return(myprintf(buffer, template, data));
  424. }
  425.  
  426.  
  427. ///
  428. /// "ARexx"
  429.  
  430. /* ---------------------------------- SendRexxCommand -------------------------
  431.  
  432.  Send ARexx message & wait for answer. Return pointer to result or NULL.
  433.  
  434. */
  435.  
  436. ULONG *
  437. SendRexxCommand(port, cmd, replyPort)
  438.  
  439. struct MsgPort *replyPort;
  440. UBYTE          *cmd, *port;
  441. {
  442.     struct MsgPort *rexxport;
  443.  
  444.     Forbid();
  445.  
  446.     if (rexxport = FindPort(port)) {
  447.  
  448.         struct RexxMsg *rexxMsg, *answer;
  449.  
  450.         if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
  451.  
  452.             if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
  453.  
  454.                 static ULONG result;
  455.  
  456.                 rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
  457.  
  458.                 PutMsg(rexxport, &rexxMsg->rm_Node);
  459.  
  460.                 do {
  461.                     
  462.                     WaitPort(replyPort);
  463.  
  464.                     if (answer = (struct RexxMsg *)GetMsg(replyPort))
  465.                         result = answer->rm_Result1;
  466.  
  467.                 } while (!answer);
  468.  
  469.                 Permit();
  470.  
  471.                 if (answer->rm_Result1 == RC_OK) 
  472.                     if (answer->rm_Result2)
  473.                         DeleteArgstring((UBYTE *)answer->rm_Result2);
  474.  
  475.                 DeleteArgstring((UBYTE *)ARG0(answer));
  476.  
  477.                 DeleteRexxMsg(answer);
  478.  
  479.                 return(&result);
  480.             }
  481.         }
  482.     }
  483.  
  484.     Permit();
  485.  
  486.     return(NULL);
  487. }
  488.  
  489. ///
  490.